﻿using System.Globalization;
/*
 * Created by SharpDevelop.
 * User: Masy Freddy
 * Date: 20/09/2011
 * Time: 16:58
 */

namespace ReaderMediaBrowser
{
	using System;
	using System.Collections.Generic;
	using System.IO;
	using System.Linq;
	using System.Xml.Serialization;

	using MetaVideoEditorEvolved.AddIn.AddInViews;
	using MetaVideoEditorEvolved.AddIn.Entity;
	using MetaVideoEditorEvolved.Helper;

	[System.AddIn.AddIn("MediaBrowser Reader",
	                    Version = "1.0.0.0",
	                    Description = "MediaBrowser Reader",
	                    Publisher = "Masy Freddy")]
	public class MediaBrowser : ReaderView
	{
		private const string MetadataFilename = "mymovies.xml",
		MetadataSerieFilename = "series.xml",
		NewMetadaFileName = "movie.xml";
		
		private ConfigurationAddIn configurationAddIn;
		
		public MediaBrowser()
		{
			configurationAddIn = ConfigurationManager.Deserialize();
			
			if(configurationAddIn == null)
			{
				configurationAddIn = new ConfigurationAddIn()
				{
					PathImagesByName = string.Empty,
					TraceLevel = "Error"
				};
				
				ConfigurationManager.Serialize(configurationAddIn);
			}
			
			Tracer.TracerInstance.Level= string.IsNullOrEmpty(configurationAddIn.TraceLevel) ? TracerLevel.Error : (TracerLevel)Enum.Parse(typeof(TracerLevel), configurationAddIn.TraceLevel);
			Tracer.TracerInstance.FileName = "MediaBrowserReader";
		}
		
		public override void ShowOption()
		{
			new Option(configurationAddIn).ShowDialog();
		}
		
		public override Movie ReadMovie(string mediaLocation)
		{
			try
			{
				Tracer.TracerInstance.TraceInformation("Start the MediaBrowser Reader for the location : " + mediaLocation);
				Title searchMovie  = null;
				
				string metadataPath = Path.Combine(mediaLocation, NewMetadaFileName);
				
				if (!File.Exists(metadataPath)) {
					Tracer.TracerInstance.TraceInformation("The file movie.xml doesnt exist, take mymovies.xml instead, please update your files to new name");
					metadataPath = Path.Combine(mediaLocation, MetadataFilename);
				}
				
				if(File.Exists(metadataPath))
				{
					using (StreamReader sr = new StreamReader(metadataPath))
					{
						searchMovie = new XmlSerializer(typeof(Title)).Deserialize(sr) as Title;
					}
				}
				
				if(searchMovie != null)
				{
					Movie movie = new Movie()
					{
						CastMembers = new List<CastMember>()
					};
					
					if(searchMovie.Persons != null)
					{
						movie.CastMembers = new System.Collections.Generic.List<CastMember>((from p in searchMovie.Persons
						                                                                     select new CastMember
						                                                                     {
						                                                                     	FullName = p.Name,
						                                                                     	Activity = p.Type,
						                                                                     	Picture = ReadActor(p.Name),
						                                                                     	Role = p.Role
						                                                                     }).ToList());
					}
					
					movie.Duration = string.IsNullOrEmpty(searchMovie.RunningTime) ? 0 : int.Parse(searchMovie.RunningTime);
					movie.Genres = searchMovie.Genres != null ? new List<string>(searchMovie.Genres) : new List<string>();
					movie.OriginalTitle = searchMovie.OriginalTitle;
					movie.Overview = searchMovie.Description;
					movie.Rating = string.IsNullOrEmpty(searchMovie.IMDBrating) ? 0.0F : float.Parse(searchMovie.IMDBrating, CultureInfo.InvariantCulture);
					movie.Studios = searchMovie.Studios != null ? new List<string>(searchMovie.Studios) : new List<string>();
					movie.Title = searchMovie.LocalTitle;
					movie.Year = string.IsNullOrEmpty(searchMovie.ProductionYear) ? 0 : int.Parse(searchMovie.ProductionYear);
					movie.MPAARating = searchMovie.MPAARating;
					movie.Countries = searchMovie.Countries != null ? new List<string>(searchMovie.Countries) : new List<string>() ;
					movie.Trailers = ReadTrailers(mediaLocation);
					movie.Backdrops = ReadBackdrops(mediaLocation);
					movie.Posters = File.Exists(Path.Combine(mediaLocation, "folder.jpg")) ?
						new List<Uri>()
					{
						new Uri(Path.Combine(mediaLocation, "folder.jpg"))
					}	: new List<Uri>();
					
					Tracer.TracerInstance.TraceSuccessOperation("End the MediaBrowser ReaderMovie for the location : " + mediaLocation);
					
					return movie;
				}
				
				return null;
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError("Exception in the ReadMovie of MediaBrowser in location " + mediaLocation, ex);
				throw;
			}
		}
		
		public override Serie ReadSerie(string mediaLocation)
		{
			Series xmlSerie  = null;
			
			try
			{
				XmlSerializer xs = new XmlSerializer(typeof(Series));
				string metadataPath = Path.Combine(mediaLocation, MetadataSerieFilename);
				
				if(File.Exists(metadataPath))
				{
					using (StreamReader sr = new StreamReader(metadataPath))
					{
						xmlSerie = xs.Deserialize(sr) as Series;
					}
				}
				
				Serie serie = null;
				
				if(xmlSerie != null)
				{
					serie = new Serie();
					serie.Graphicals = File.Exists(Path.Combine(mediaLocation, "banner.jpg")) ?
						new List<Uri>()
					{
						new Uri(Path.Combine(mediaLocation, "banner.jpg"))
					}	: new List<Uri>();
					serie.Backdrops = ReadBackdrops(mediaLocation);
					
					serie.CastMembers = xmlSerie.Actors == null ? new List<CastMember>() : (from a in xmlSerie.Actors.Trim('|').Split('|')
					                                                                        select new CastMember
					                                                                        {
					                                                                        	FullName = a,
					                                                                        	Picture = ReadActor(a),
					                                                                        	Activity = "Actor"
					                                                                        }).ToList();
					
					serie.Duration = string.IsNullOrEmpty(xmlSerie.Runtime) ? 0 : int.Parse(xmlSerie.Runtime);
					serie.Genres = xmlSerie.Genre == null ? new List<string>() : xmlSerie.Genre.Trim('|').Split('|').ToList();
					serie.Name = xmlSerie.SeriesName;
					serie.Overview = xmlSerie.Overview;
					serie.Posters = File.Exists(Path.Combine(mediaLocation, "folder.jpg")) ?
						new List<Uri>()
					{
						new Uri(Path.Combine(mediaLocation, "folder.jpg"))
					}	: new List<Uri>();
					serie.Rating = float.Parse(xmlSerie.Rating.ToString(), CultureInfo.InvariantCulture);
					serie.Studios = string.IsNullOrEmpty(xmlSerie.Network) ? new List<string>() : xmlSerie.Network.Trim('|').Split('|').ToList();
					serie.Id = xmlSerie.id;
				}
				
				return serie;
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(string.Format("Exception MediaBrowser ReadSerie mediaLocation={0}", mediaLocation), ex);
				throw;
			}
		}
		
		public override Episode ReadEpisode(string mediaLocation)
		{
			try
			{
				Tracer.TracerInstance.TraceInformation("ReadEpisode from MediaBrowser in " + mediaLocation);
				Item searchEpisode  = null;
				
				FileInfo fi = new FileInfo(mediaLocation);
				string metadataPath = Path.Combine(fi.Directory.FullName, "metadata\\" + fi.Name.Replace(fi.Extension, ".xml"));
				
				if(File.Exists(metadataPath))
				{
					using (StreamReader sr = new StreamReader(metadataPath))
					{
						searchEpisode = new XmlSerializer(typeof(Item)).Deserialize(sr) as Item;
					}
				}
				
				if(searchEpisode != null)
				{
					return new Episode()
					{
						Images = File.Exists(Path.Combine(fi.Directory.FullName, "metadata\\" + fi.Name.Replace(fi.Extension, ".jpg"))) ?
							new List<Uri>()
						{
							new Uri(Path.Combine(fi.Directory.FullName, "metadata\\" + fi.Name.Replace(fi.Extension, ".jpg")))
						}	: new List<Uri>(),
						Name = searchEpisode.EpisodeName,
						Overview = searchEpisode.Overview,
						Rating =string.IsNullOrEmpty(searchEpisode.Rating) ? 0 : float.Parse(searchEpisode.Rating.ToString(), CultureInfo.InvariantCulture),
						Directors = string.IsNullOrEmpty(searchEpisode.Directors) ? new List<string>() : searchEpisode.Directors.Trim('|').Split('|').ToList(),
						GuestStars = string.IsNullOrEmpty(searchEpisode.GuestStars) ? new List<string>() : searchEpisode.GuestStars.Trim('|').Split('|').ToList(),
						Writers = string.IsNullOrEmpty(searchEpisode.Writer) ? new List<string>() : searchEpisode.Writer.Trim('|').Split('|').ToList(),
						SeasonNumber = string.IsNullOrEmpty(searchEpisode.SeasonNumber) ? 0 : int.Parse(searchEpisode.SeasonNumber),
						Number = string.IsNullOrEmpty(searchEpisode.EpisodeNumber) ? 0 : int.Parse(searchEpisode.EpisodeNumber)
					};
				}
				
				return null;
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(string.Format("Exception in MediaBrowser ReadEpisode mediaLocation={0}", mediaLocation), ex);
				throw;
			}
		}
		
		public override Season ReadSeason(string mediaLocation)
		{
			try
			{
				Tracer.TracerInstance.TraceInformation("ReadSeason from Mediabrowser in " + mediaLocation);
				
				return new Season()
				{
					Images = File.Exists(Path.Combine(mediaLocation, "folder.jpg")) ?
						new List<Uri>()
					{
						new Uri(Path.Combine(mediaLocation, "folder.jpg"))
					}	: new List<Uri>()
				};
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(string.Format("Exception in MediaBrowser ReadSeason mediaLocation={0}", mediaLocation), ex);
				throw;
			}
		}
		
		private Uri ReadActor(string fullName)
		{
			if(!string.IsNullOrEmpty(configurationAddIn.PathImagesByName))
			{
				// Remove special char like \t
				fullName = fullName.Replace("\t",string.Empty);
				
				var imagePath = Path.Combine(configurationAddIn.PathImagesByName, "People", fullName, "folder.jpg");
				
				if(File.Exists(imagePath))
				{
					return new Uri(imagePath);
				}
			}
			
			return null;
		}
		
		private List<Uri> ReadBackdrops(string mediaLocation)
		{
			return (from b in new DirectoryInfo(mediaLocation).GetFiles("backdrop*")
			        orderby b.FullName
			        select new Uri(b.FullName)).ToList();
		}
		
		private List<Trailer> ReadTrailers(string mediaLocation)
		{
			string trailersPath = Path.Combine(mediaLocation, "Trailers");
			
			if (Directory.Exists(trailersPath))
			{
				return (from t in new DirectoryInfo(trailersPath).GetFiles()
				        select new Trailer
				        {
				        	DefaultPath = new Uri(t.FullName)
				        }).ToList();
			}
			
			return null;
		}
		
		public override bool HasOption()
		{
			return true;
		}
	}
}
